package laschools.team1.Zelda;

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;
import java.util.Random;
import java.util.Scanner;

import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;

@SuppressWarnings("serial")
public class Main extends JApplet implements Runnable {
	
	
	static double x_pos = 8;
	static double y_pos = 6;
	static int squareLength = 40;
	static int HUDheight;

	public static double getLinkPosX() {
		return x_pos;
	}
	
	public static double getLinkPosY() {
		return y_pos;
	}
	
	public static int getSquareLength() {
		return squareLength;
	}
	
	public static int getHUDheight() {
		return HUDheight;
	}

	Link link = new Link();

	int radius = 20;
	int step = 2;
	int direction = 1;
	Random gen = new Random();
	Monster octorock = new Monster(1, 50, 250);
	int runs = 0;
	int monsterStep;
	
	
	boolean keepPlayingSameSong = true;

	char[][] screen = new char[16][11];
	Scanner scan = new Scanner(System.in);
	int xScreen = 8, yScreen = 1;

	Point location;
	Point lastLocation = new Point(0, 0);
	
	Image LinkRight1;
	Image LinkRight2;
	Image LinkRightAtt1;
	Image LinkLeft1;
	Image LinkLeft2;
	Image LinkLeftAtt1;
	Image LinkUp1;
	Image LinkUp2;
	Image LinkUpAtt1;
	Image LinkDown1;
	Image LinkDown2;
	Image LinkDownAtt1;
	Image hud;
	Image fullHeartLeft;
	Image fullHeartRight;
	Image emptyHeartRight;
	Image emptyHeartLeft;

	Image tempLink1;
	Image tempLink2;

	Terrain terrain;

	// Monster Images
	Image octorockRight1;
	Image octorockRight2;
	Image octorockLeft1;
	Image octorockLeft2;
	Image octorockUp1;
	Image octorockUp2;
	Image octorockDown1;
	Image octorockDown2;
	Image rockBullet;
	
	
	Sound theme;
	Sound arrow;
	
	JPanel panel;

	/**
	 * @param args
	 */
	// public static void main(String[] args) {
	//
	// }

	public void init() {
		setSize(800, 750);
		addKeyListener(new ZeldaListener());
		LinkRight1 = new ImageIcon(getCodeBase().getPath() + "Sprites/LinkRight1.png").getImage();
		LinkRight2 = new ImageIcon(getCodeBase().getPath() + "Sprites/LinkRight2.png").getImage();
		LinkRightAtt1 = new ImageIcon(getCodeBase().getPath() + "Sprites/LinkRightAtt1.png").getImage();
		LinkLeft1 = new ImageIcon(getCodeBase().getPath() + "Sprites/LinkLeft1.png").getImage();
		LinkLeft2 = new ImageIcon(getCodeBase().getPath() + "Sprites/LinkLeft2.png").getImage();
		LinkLeftAtt1 = new ImageIcon(getCodeBase().getPath() + "Sprites/LinkLeftAtt1.png").getImage();
		LinkUp1 = new ImageIcon(getCodeBase().getPath() + "Sprites/LinkUp1.png").getImage();
		LinkUp2 = new ImageIcon(getCodeBase().getPath() + "Sprites/LinkUp2.png").getImage();
		LinkUpAtt1 = new ImageIcon(getCodeBase().getPath() + "Sprites/LinkUpAtt1.png").getImage();
		LinkDown1 = new ImageIcon(getCodeBase().getPath() + "Sprites/LinkDown1.png").getImage();
		LinkDown2 = new ImageIcon(getCodeBase().getPath() + "Sprites/LinkDown2.png").getImage();
		LinkDownAtt1 = new ImageIcon(getCodeBase().getPath() + "Sprites/LinkDownAtt1.png").getImage();

		// Hud images
		hud = new ImageIcon(getCodeBase().getPath() + "Sprites/Zelda Hud.png").getImage();
		fullHeartLeft = new ImageIcon(getCodeBase().getPath() + "Sprites/FullHeartLeft.png").getImage();
		fullHeartRight = new ImageIcon(getCodeBase().getPath() + "Sprites/FullHeartRight.png").getImage();
		emptyHeartRight = new ImageIcon(getCodeBase().getPath() + "Sprites/EmptyHeartRight.png")
				.getImage();
		emptyHeartLeft = new ImageIcon(getCodeBase().getPath() + "Sprites/EmptyHeartLeft.png").getImage();

		terrain = new Terrain();
		
		octorockRight1 = new ImageIcon(getCodeBase().getPath() + "Sprites/OctorockRight1.png").getImage();
		octorockRight2 = new ImageIcon(getCodeBase().getPath() + "Sprites/OctorockRight2.png").getImage();
		octorockLeft1 = new ImageIcon(getCodeBase().getPath() + "Sprites/OctorockLeft1.png").getImage();
		octorockLeft2 = new ImageIcon(getCodeBase().getPath() + "Sprites/OctorockLeft2.png").getImage();
		octorockUp1 = new ImageIcon(getCodeBase().getPath() + "Sprites/OctorockUp1.png").getImage();
		octorockUp2 = new ImageIcon(getCodeBase().getPath() + "Sprites/OctorockUp2.png").getImage();
		octorockDown1 = new ImageIcon(getCodeBase().getPath() + "Sprites/OctorockDown1.png").getImage();
		octorockDown2 = new ImageIcon(getCodeBase().getPath() + "Sprites/OctorockDown2.png").getImage();

		rockBullet = new ImageIcon(getCodeBase().getPath() + "Sprites/rockBullet.png").getImage();
		tempLink1 = LinkDown1;
		tempLink2 = LinkDown2;
		
		theme = new Sound("Sounds/theme.wav");
		arrow = new Sound("Sounds/LOZ_Arrow.wav");

		panel = new JPanel();
		
		int y_pos = 7;
		int x_pos = 8;

		this.add(panel);
		panel.add(new JTextField("Helllooo!!:"));
		
		setupKeyBindings();
		panel.requestFocusInWindow();
	}
	
	private void setupKeyBindings(){
		panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP,direction), "Up");
		panel.getActionMap().put("Up", new AbstractAction() {
			public void actionPerformed(ActionEvent ae) {
				System.out.println("Hello " + ae);
            }
        });

		System.out.println("HellO");
	}

	public void start() {
		Thread th = new Thread(this);
		HUDheight = getHeight() * 4 / 15;
		squareLength = ((getHeight() - squareLength  * 4) / 11);
		th.start();
		theme.playSound();

	}

	public void stop() {
	}

	public void destroy() {
	}

	public void run() {
		squareLength = (int) (((0.75 * getHeight()) / 11));
		HUDheight = getHeight() * 4 / 15;
		monsterStep = 100;
		if (keepPlayingSameSong){
			//The same song will keep playing. No action required.
		}
		else {
			theme.stopSound();
			//We need to play a different song. Which one? That will be figured out in another class!!
		}

		// Stop thread for 10 milliseconds
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// do nothing
		// repaint the applet

		repaint();

		// set ThreadPriority to maximum value
		Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
		// System.out.println(step);
		runs++;

		// run a long while (true) this means in our case "always"
		while (link.getAlive()) {
			run();
		}

		System.exit(0);
	}

	public void paint(Graphics page) {

		// Paints the screen
		String screenName = "laschools/team1/Zelda/" + xScreen + "-" + yScreen + ".txt";

		screen = ScreenScanner.scanScreen(screenName);

		// Painting

		// paints hud
		page.drawImage(hud, 0, 0, squareLength * 16, HUDheight, this);

		//paints hearts
		for (int i = 0; i < link.getMaxHealth(); i++) {
			if (i % 2 == 0) {
				page.drawImage(emptyHeartLeft, (550 + (i * 11)), 150, 20, 30,
						this);
			} else if (i % 2 == 1) {
				page.drawImage(emptyHeartRight, (549 + (i * 11)), 150, 20, 30,
						this);
			}
		}

		for (int i = 0; i < link.getHealth(); i++) {
			if (i % 2 == 0) {
				page.drawImage(fullHeartLeft, (550 + (i * 11)), 150, 20, 30,
						this);
			} else if (i % 2 == 1) {
				page.drawImage(fullHeartRight, (549 + (i * 11)), 150, 20, 30,
						this);
			}
		}

		// link.takeDamage(1);

		page.setColor(Color.green);
		page.fillRect(squareLength + (xScreen * (squareLength / 4)),
				(HUDheight - (squareLength / 2)) - (yScreen * (squareLength / 4)),
				(squareLength / 4), (squareLength / 4));
		
		Terrain.drawTerrain(page, screen);
		
		if (step % 2 == 0) {
			page.drawImage(tempLink1, ((int) (x_pos * squareLength)), (int) ((y_pos * squareLength) + HUDheight), squareLength, squareLength, this);
		} else if (step % 2 == 1) {
			page.drawImage(tempLink2, ((int) (x_pos * squareLength)), (int) ((y_pos * squareLength) + HUDheight), squareLength, squareLength, this);
		}

		// Paints Monsters
		int octorockX = octorock.getXPos();
		int octorockY = octorock.getYPos();

		switch (octorock.getDirection()) {
		case 1:
			if ((octorock.getNumSteps()) % 2 == 0) {
				page.drawImage(octorockUp1, octorockX, octorockY, squareLength,
						squareLength, this);
			} else if ((octorock.getNumSteps()) % 2 == 1) {
				page.drawImage(octorockUp2, octorockX, octorockY, squareLength,
						squareLength, this);
			}
			break;
		case 2:
			if ((octorock.getNumSteps()) % 2 == 0) {
				page.drawImage(octorockRight1, octorockX, octorockY,
						squareLength, squareLength, this);
			} else if ((octorock.getNumSteps()) % 2 == 1) {
				page.drawImage(octorockRight2, octorockX, octorockY,
						squareLength, squareLength, this);
			}
			break;
		case 3:
			if ((octorock.getNumSteps()) % 2 == 0) {
				page.drawImage(octorockDown1, octorockX, octorockY,
						squareLength, squareLength, this);
			} else if ((octorock.getNumSteps()) % 2 == 1) {
				page.drawImage(octorockDown2, octorockX, octorockY,
						squareLength, squareLength, this);
			}
			break;
		case 4:
			if ((octorock.getNumSteps()) % 2 == 0) {
				page.drawImage(octorockLeft1, octorockX, octorockY,
						squareLength, squareLength, this);
			} else if ((octorock.getNumSteps()) % 2 == 1) {
				page.drawImage(octorockLeft2, octorockX, octorockY,
						squareLength, squareLength, this);
			}
			break;
		default:
			page.drawImage(octorockLeft1, 500, 300, squareLength, squareLength,
					this);
			break;
		}

		octorock.lookForLink();

		if (octorock.seesLink()) {
			// page.drawImage(rockBullet, (octorock.getXPos() + 800),
			// octorock.getYPos(), 50, 50, this);

		} else {
			if (runs % 100 == 0) {
				octorock.step();
			}
		}
	}

	private class ZeldaListener implements KeyListener {
		public void keyPressed(KeyEvent e) {
			int keyCode = e.getKeyCode();
			
			if (keyCode == KeyEvent.VK_UP) {
				arrow.playSoundOnce();
				tempLink1 = LinkUp1;
				tempLink2 = LinkUp2;
				direction = 0;
				if (y_pos <= 0
						|| (screen[(int) x_pos][(int) (y_pos - 0)] == 'd'
						&& screen[(int) (x_pos + 0.5)][(int) (y_pos - 0)] == 'd')) {
					y_pos -= 0.5;
				}

				step++;

				if (y_pos < 0) {
					yScreen++;
					y_pos = 10;
				}
			}
			else if (keyCode == KeyEvent.VK_RIGHT) {
				tempLink1 = LinkRight1;
				tempLink2 = LinkRight2;
				direction = 1;
				if (x_pos >= (15)
						|| screen[(int) (x_pos) + 1][(int) (y_pos + 0.5)] == 'd') {
					x_pos += 0.5;
				}

				step++;

				// change screen
				if (x_pos > 15) {
					x_pos = 0;
					xScreen++;
				}
			}
			else if (keyCode == KeyEvent.VK_LEFT) {
				tempLink1 = LinkDown1;
				tempLink2 = LinkDown2;
				direction = 2;
				if (y_pos >= 10
						|| ((screen[(int) (x_pos)][(int) (y_pos) + 1] == 'd') 
							&& (screen[(int) (x_pos + 0.5)][(int) (y_pos) + 1] == 'd'))) {
					y_pos += 0.5;
				}

				step++;

				// Change screen
				if (y_pos > 10) {
					yScreen--;
					y_pos = 0;
				}
			}
			else if (keyCode == KeyEvent.VK_DOWN) {
				tempLink1 = LinkLeft1;
				tempLink2 = LinkLeft2;
				
				direction = 3;
				if (x_pos <= 0
						|| (screen[(int) (x_pos - 0.5)][(int) (y_pos + 0.5)] == 'd')) {
					x_pos -= 0.5;
				}

				step++;

				// Change screen
				if (x_pos < 0) {
					xScreen--;
					x_pos = 15;
				}
			}
		}

		@Override
		public void keyReleased(KeyEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void keyTyped(KeyEvent arg0) {
			// TODO Auto-generated method stub
			
		}
	}
	
	public class Sound // Holds one audio file
	{
		private AudioClip song; // Sound player
		private URL songPath; // Sound path
		Sound(String filename)
		{
			try
			{
				songPath = new URL(getCodeBase(),filename); // Get the Sound URL
				song = Applet.newAudioClip(songPath); // Load the Sound
			}
			catch(Exception e){} // Satisfy the catch

		}
		public void playSound()
		{
			song.loop(); // Play 
		}
		public void stopSound()
		{
			song.stop(); // Stop
		}
		public void playSoundOnce()
		{
			song.play(); // Play only once
		}
	}	
}